Skip to content

patina_dxe_core: Add DxeDispatch service for driver dispatch#1421

Open
kat-perez wants to merge 1 commit intoOpenDevicePartnership:mainfrom
kat-perez:kp/expose-core-dispatch
Open

patina_dxe_core: Add DxeDispatch service for driver dispatch#1421
kat-perez wants to merge 1 commit intoOpenDevicePartnership:mainfrom
kat-perez:kp/expose-core-dispatch

Conversation

@kat-perez
Copy link
Contributor

@kat-perez kat-perez commented Mar 19, 2026

Description

Add a DxeDispatch service trait in the SDK and a CoreDxeDispatch
implementation in patina_dxe_core that delegates to the PI dispatcher.
The service is registered alongside other core services (MemoryManager,
PerfTimer, etc.) and consumed via dependency injection by components
that need to trigger driver dispatch passes.

  • Impacts functionality?
  • Impacts security?
  • Breaking change?
  • Includes tests?
  • Includes documentation?

How This Was Tested

  • Built SBSA DXE core binary with BootDispatcher + SimpleBootManager consuming the service via DI
  • Booted Windows ARM64 under QEMU SBSA-ref with Patina BDS handling the full boot flow
  • Connect-dispatch interleaving discovered AHCI device, expanded partial device path, loaded Windows bootloader, ExitBootServices completed
  • 106 on-system unit tests passed (0 fails)

Integration Instructions

The DxeDispatch service is registered automatically by the DXE core.
Components consume it via dependency injection:

fn entry_point(self, dxe_dispatch: Service<dyn DxeDispatch>) -> Result<()> {
    dxe_dispatch.dispatch()?;
    Ok(())
}

@patina-automation
Copy link
Contributor

patina-automation bot commented Mar 19, 2026

✅ QEMU Validation Passed

All QEMU validation jobs completed successfully.

Note: Q35 is only built on Windows hosts (QEMU boot is disabled due to a QEMU vfat issue).

Workflow run: https://github.com/OpenDevicePartnership/patina/actions/runs/23465890837

Boot Time to EFI Shell

Platform Elapsed
Q35 (Linux Host) 28.4s
SBSA (Linux Host) 35.5s

Dependencies

Repository Ref
patina 6a617c3
patina-dxe-core-qemu 4f98fff
patina-fw-patcher 3b8900d
patina-qemu firmware v2.0.0
patina-qemu build script b20729a

This comment was automatically generated by the Patina QEMU PR Validation Post workflow.

@codecov
Copy link

codecov bot commented Mar 19, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@kat-perez kat-perez force-pushed the kp/expose-core-dispatch branch from b8285d5 to 527b860 Compare March 19, 2026 18:51
@kat-perez kat-perez marked this pull request as ready for review March 19, 2026 18:56
/// Performs a single DXE driver dispatch pass.
///
/// Returns `true` if any drivers were dispatched, `false` if no drivers remain.
pub fn dispatch(&'static self) -> Result<bool> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think making this public makes sense. @Javagedes do you have thoughts on this? Feels like a different paradigm is needed.

Copy link
Contributor Author

@kat-perez kat-perez Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could move this to the SDK instead?

Like this at sdk/patina/src/pi/dxe_services.rs?

/// Interface for dispatching DXE drivers.
///
/// Boot orchestrators use this to interleave controller connection
/// with driver dispatch.
pub trait DxeServices: Send + Sync + 'static {
    /// Run a single dispatch pass. Returns `true` if any drivers were dispatched.
    fn dispatch(&self) -> crate::error::Result<bool>;
}

Copy link
Contributor

@Javagedes Javagedes Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I don't think we want to make this public outside of the core. It leaks containment of functionality that the platform's top level main() function should not have access to, which could result in platforms doing bad things.

Based off of the current usage:

impl DxeServices for CoreDxeServices {
    fn dispatch(&self) -> patina::error::Result<bool> {
        CORE.dispatch()
    }
}

// Boot orchestration with connect-dispatch interleaving
add.component(BootDispatcher::new(
  SimpleBootManager::new(
    BootConfig::new(create_boot_path())
      .with_failure_handler(|| log::error!("Boot failed: all boot options exhausted")),
    ),
    CoreDxeServices,
));

I think one of these two options better lean into the patina component model via dependency injection:

  1. Create a new service trait defined in the patina crate for either (1) only dispatch or (2) the entire dxe services table, and implemented in the core (Similar to the CoreMemoryManager), then consume it through dependency injection
  2. Do the same as 1, but instead do it for configuration table functionality, then you can grab the dxe services configuration table and call dispatch from dxe_services

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I'll go with (1.) by making a new service trait instead. Would be something like CoreDxeDispatch, implemented like CoreMemoryManager

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The platform binary will never touch dispatch() directly

@kat-perez kat-perez force-pushed the kp/expose-core-dispatch branch from 527b860 to 386036d Compare March 20, 2026 18:28
@kat-perez kat-perez changed the title patina_dxe_core: Expose Core::dispatch() for boot orchestrators patina_dxe_core: Add DxeDispatch service for driver dispatch Mar 20, 2026
@kat-perez kat-perez force-pushed the kp/expose-core-dispatch branch 6 times, most recently from c8162fd to 762aa1d Compare March 23, 2026 17:39
@kat-perez
Copy link
Contributor Author

@os-d @Javagedes this is ready for another review. thanks!

pub trait DxeDispatch {
/// Performs a single DXE driver dispatch pass.
///
/// Returns `true` if any drivers were dispatched, `false` if no drivers remain.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe false means no drivers were dispatched, not necessarily that there are no more remaining drivers.

Copy link
Contributor

@os-d os-d left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the overall approach is reasonable, we would want the other dispatch services also defined at some point, but I think it is okay to defer those until a use case arises

impl CoreDxeDispatch {
/// Create a new dispatch service with the given dispatch function.
pub(crate) fn new(dispatch_fn: fn() -> Result<bool>) -> Self {
Self(dispatch_fn)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this configurable? Can we not just always use the pi_dispatcher?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably for mocking.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't the whole trait just be mocked?

Copy link
Contributor

@Javagedes Javagedes Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair :) I concur with @os-d we should just hardcode in the usage of the core instead of having the wrapper like this.

Also if you update init_memory to be &'static self (which I think is fair), then I think you could even do something like this:

pub(crate) struct CoreDxeDispatch<P: PlatformInfo>(&'static Core<P>);

// ...

component_dispatcher.add_service(dxe_dispatch_service::CoreDxeDispatch::new(self);

I'm not 100% confident in that though.

@kat-perez kat-perez force-pushed the kp/expose-core-dispatch branch 2 times, most recently from 7469952 to 00af474 Compare March 23, 2026 19:15
@kat-perez kat-perez requested review from Javagedes and os-d March 23, 2026 19:16
@kat-perez kat-perez force-pushed the kp/expose-core-dispatch branch 4 times, most recently from df163af to 1d334a4 Compare March 23, 2026 23:35
@kat-perez kat-perez force-pushed the kp/expose-core-dispatch branch from 1d334a4 to 6a617c3 Compare March 23, 2026 23:36
@kat-perez kat-perez force-pushed the kp/expose-core-dispatch branch from 6a617c3 to 0fae68c Compare March 23, 2026 23:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants